package com.indusfo.spc.controller;

import com.indusfo.spc.config.PieceFlowConfig;
import com.indusfo.spc.exception.GlobalException;
import com.indusfo.spc.exception.UploadErrorException;
import com.indusfo.spc.pojo.ExcelErrorData;
import com.indusfo.spc.pojo.ProfileDetail;
import com.indusfo.spc.service.ProfileDetailService;
import com.indusfo.spc.untlis.*;
import com.indusfo.spc.vo.JSONObject;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author chenm
 * 工艺文件库控制类
 * @create 2019-11-27 9:49
 */
@RestController
@RequestMapping("/service/profileDetail")
public class ProfileDetailController {

    @Autowired
    private ProfileDetailService profileDetailService;


    //文件上传
    @RequestMapping(value = "/insertFile")
    public JSONObject insertFile(@RequestParam(value = "file") MultipartFile file) {
        try {
            // 获取当前时间
            Date date = new Date();
            // 获取文件名
            String content = file.getOriginalFilename();

            // 转换为统一的小写形式
            String fileName = content.toLowerCase();

            // 获取图片的后缀名.doc
            String fileType = fileName.substring(fileName.lastIndexOf("."));

            // 判断是否为word文档,excel文档,pdf文件的类型
            if (!fileName.matches("^.*(doc|docx|xls|xlsx|xl|xla|xlt|xlm|xlc|xlw|pdf|png|jpg|jpeg)$")) {
                // 说明:如果传递的文件不是指定的格式,直接程序结束
                throw new UploadErrorException("上传的文件格式不符合要求");
            }
            // 将文件分年月存储 yyyy/MM/dd
            String datePath = new SimpleDateFormat("yyyy/MM/dd").format(date);
            // 存放的目标目录
            String target = PieceFlowConfig.getProfile();
            // 判断是否有该文件夹:项E/upload/2018/10/09
            String fileDir = target + datePath;
            File fileFile = new File(fileDir);

            if (!fileFile.exists()) {
                // 没有则创建目录
                fileFile.mkdirs();
            }

            // 生成图片唯一标识码
            String uuid = UuidUtil.getUuid();

            // 拼接文件的名称
            String fileNowName = uuid + fileType;
            // 实现文件保存:E/upload/yyyy/MM/dd/1231231231231231231.jpg
            String realFilePath = fileDir + "/" + fileNowName;
            file.transferTo(new File(realFilePath));


            // 开启一个线程，去执行word转pdf转png动作,图片格式不需要转换
            if (fileType.matches("^.*(png|jpg|jpeg)$")) {
                realFilePath = "/upload/" + datePath + "/" + fileNowName;
            } else {
                OfficeTransformThread officeT = new OfficeTransformThread(realFilePath);
                new Thread(officeT).start();
                realFilePath = "/upload/" + datePath + "/" + uuid + ".pdf";
            }
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
            Map<String, Object> map = new HashMap<>();
            map.put("content", content);
            map.put("relUrl", realFilePath);
            map.put("uuid", UuidUtil.getUuid());
            map.put("modifyDate", df.format(date));
            // 将路径返回
            return JSONObject.build(JSONObject.SUCCESS, "保存成功!", map);
        } catch (GlobalException e) {
            // 捕获异常,打印并返回
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR, e.getMessage());
        } catch (IllegalStateException e) {
            // 捕获异常,打印并返回
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR, e.getMessage());
        } catch (IOException e) {
            // 捕获异常,打印并返回
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR, e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR, e.getMessage());
        }
    }

    /*
      查询文件
      */
    @RequestMapping(value = "/selectProFileList")
    public JSONObject selectProFileList(ProfileDetail profileDetail) {
        try {
            if (profileDetail.getMatId() == null) {
                throw new Exception("物料id不能为空");
            }
            /*
            if (profileDetail.getMatVerId() == null) {
                throw new Exception("物料版本id不能为空");
            }
            */
            List<ProfileDetail> profileDetails = profileDetailService.selectProFileList(profileDetail);
            return JSONObject.build(JSONObject.SUCCESS, "查询成功", profileDetails);
        } catch (Exception e) {
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR, e.getMessage());
        }
    }

    @RequestMapping("/uploadFileProfileDetails")
    @ResponseBody
    public JSONObject uploadFileProFiles(@RequestParam("file") MultipartFile file, Boolean way, HttpServletRequest request, HttpServletResponse response) {

        //初始化一个新文件用来接收前端传递的压缩包
        File newFile = null;
        //初始化一个excel文件作为用户上传的模板
        File excelFile = new File("");
        try {
            //MultipartFile转换为File存储到服务器目录下
            String path = PieceFlowConfig.getProfile();
            newFile = new File(new File(path).getAbsolutePath() + File.separator + file.getOriginalFilename());
            file.transferTo(newFile);

            //定义一个JSONObject对象用于向前台传输数据
            JSONObject jsonObject = new JSONObject();
            jsonObject.setStatus(JSONObject.ERROR);
            //定义一个文件集合用来存放解压后的文件
            //获取上传的文件名
            String fileName = newFile.getName();
            // 获取文件的后缀名.doc
            String fileType = fileName.substring(fileName.lastIndexOf("."));
            //首先判断当前上传的文件是否是压缩包格式的
            if (fileType.equals(".zip")) {
                // 存放的目标目录
                String target = PieceFlowConfig.getProfile() + File.separator + UuidUtil.getUuid();
                //解压到指定目录
                FileUnZip.zipToFile(newFile, target);
                //解压后将服务器保存的压缩包删除
                newFile.delete();
                List<File> fileList = new ArrayList<>();
                //获取到该路径下的所有文件
                List<File> allFiles = FileUtil.getAllFiles(target, fileList);
                for (File zipFile : allFiles) {
                    String name = zipFile.getName();
                    //找到对应的模板
                    if ("工艺文件库模板.xlsx".equals(name) && "xlsx".equals(name.substring(name.lastIndexOf(".") + 1))) {
                        excelFile = zipFile;
                        jsonObject.setStatus(JSONObject.SUCCESS);
                        break;
                    }
                }
                if (jsonObject.getStatus().equals(JSONObject.ERROR)) {
                    return JSONObject.build(jsonObject.getStatus(), "未上传指定模版");
                }
                //设置错误集合
                List<ExcelErrorData> errorDatas = new ArrayList<>();
                //判断上传文件格式是否正确
                Workbook wb = ExcelUtil.getWorkbook(new FileInputStream(excelFile), ExcelUtil.isExcel2007(excelFile.getName()));
                if (wb == null) {
                    jsonObject.setStatus(JSONObject.ERROR);
                    jsonObject.setMsg("Excel文件解析错误");
                    errorDatas.add(ExcelErrorData.getExcelErrorData(0, 0, "Excel文件解析错误"));
                } else {
                    //获取excel文件的第一个sheet
                    //获取当前表编码所对应的表
                    Sheet sheet = wb.getSheetAt(0);
                    if (sheet == null) {
                        jsonObject.setStatus(JSONObject.ERROR);
                        jsonObject.setMsg("未找到需要导入的表格");
                        errorDatas.add(ExcelErrorData.getExcelErrorData(0, 0, "未找到需要导入的表格"));
                    } else {
                        //获取最后一行的行号
                        int rowCount = sheet.getLastRowNum();
                        if (rowCount < 1) {
                            jsonObject.setStatus(JSONObject.ERROR);
                            jsonObject.setMsg("未找到需要导入的数据，请确认表格是否保存！！！");
                            errorDatas.add(ExcelErrorData.getExcelErrorData(0, "未找到需要导入的数据，请确认表格是否保存！！！"));
                        } else {
                            List<ProfileDetail> profileDetailList = new ArrayList<>();
                            for (int i = 1; i <= rowCount; i++) {
                                boolean needAdd = true;
                                //获取到每一行的每一列的数据
                                //产品编码
                                String matModel = ExcelUtil.getCellValue(sheet, i, 0, false);
                                /*//版本名称
                                String matVerName = ExcelUtil.getCellValue(sheet, i, 1, false);*/
                                //工序名称
                                String proName = ExcelUtil.getCellValue(sheet, i, 1, false);
                                //文件路径
                                String content = ExcelUtil.getCellValue(sheet, i, 2, false);
                                ProfileDetail profile = new ProfileDetail(content, proName, matModel);
                                //将excel中的每一行数据存储进行检查
                                String result = profileDetailService.checkNoRepeatExcel(profile, allFiles);
                                if (result != null) {
                                    errorDatas.add(ExcelErrorData.getExcelErrorData(i, result));
                                    needAdd = false;
                                }
                                for (int j = 1; j < i; j++) {
                                    //判断物料编码  物料名称是否重复
                                    String oldvcMatCode = ExcelUtil.getCellValue(sheet, j, 0, false);
//                                    String oldMatVerName =ExcelUtil.getCellValue(sheet, j, 1, false);
                                    String oldProName = ExcelUtil.getCellValue(sheet, j, 1, false);
                                    if (!org.apache.commons.lang3.StringUtils.isBlank(matModel) && !org.apache.commons.lang3.StringUtils.isBlank(oldvcMatCode) && oldvcMatCode.equals(matModel) &&
                                            !org.apache.commons.lang3.StringUtils.isBlank(proName) && !org.apache.commons.lang3.StringUtils.isBlank(oldProName)  && oldProName.equals(proName)) {
                                        needAdd = false;
                                        errorDatas.add(ExcelErrorData.getExcelErrorData(i, "与表格中第" + j + "行存在相同产品版本工序"));
                                    }

                                }
                                if (needAdd) {
                                    profileDetailList.add(profile);
                                } else {
                                    jsonObject.setStatus(JSONObject.ERROR);
                                    jsonObject.setMsg("导入数据中存在异常信息");
                                }
                            }
                            //根据这些来判断是否是中止导入还是跳过继续进行导入
                            if (jsonObject.getStatus().equals(JSONObject.ERROR) && !way) {
                                jsonObject.setMsg(jsonObject.getMsg() + ",中止导入");
                            } else {
                                if (profileDetailList.size() > 0) {
                                    try {
                                        profileDetailService.updateListProfileDetail(profileDetailList);

                                        //当程序执行到这里时,判断信息是否为空为空的话设置导入成功
                                        jsonObject.setMsg(StringUtils.isBlank(jsonObject.getMsg()) ? "导入成功" : jsonObject.getMsg());
                                        if ("导入成功".equals(jsonObject.getMsg())) {
                                            jsonObject.setStatus(JSONObject.SUCCESS);
                                        }

                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        jsonObject.setMsg("导入失败");
                                    } finally {
                                        //文件导入结束后删除解压的文件
                                        FileUtil.deleteFile(new File(target));
                                    }
                                }
                            }

                        }
                    }
                }
                jsonObject.setData(GsonUtil.toJson(errorDatas));
                return JSONObject.build(jsonObject.getStatus(), jsonObject.getMsg(), errorDatas);

            } else {
                return JSONObject.build(jsonObject.getStatus(), "导入文件格式不正确");
            }
        } catch (IOException e) {
            e.printStackTrace();
            return JSONObject.build(JSONObject.ERROR, "导入模版存在问题,请联系管理员");
        } catch (Exception e) {
            return JSONObject.build(JSONObject.ERROR, "导入模版存在问题,请联系管理员");
        }
    }
}
